import Vue from 'vue'
import css from 'assets/js/theme/index'
const ORIGINAL_THEME = '#2C9CFA'

function getThemeCluster(theme) {
  const tintColor = (color, tint) => {
    let red = parseInt(color.slice(0, 2), 16)
    let green = parseInt(color.slice(2, 4), 16)
    let blue = parseInt(color.slice(4, 6), 16)

    if (tint === 0) {
      return [red, green, blue].join(',')
    } else {
      red += Math.round(tint * (255 - red))
      green += Math.round(tint * (255 - green))
      blue += Math.round(tint * (255 - blue))

      red = red.toString(16)
      green = green.toString(16)
      blue = blue.toString(16)

      return `#${red}${green}${blue}`
    }
  }

  const shadeColor = (color, shade) => {
    let red = parseInt(color.slice(0, 2), 16)
    let green = parseInt(color.slice(2, 4), 16)
    let blue = parseInt(color.slice(4, 6), 16)

    red = Math.round((1 - shade) * red)
    green = Math.round((1 - shade) * green)
    blue = Math.round((1 - shade) * blue)

    red = red.toString(16)
    green = green.toString(16)
    blue = blue.toString(16)

    return `#${red}${green}${blue}`
  }

  const clusters = [theme]
  for (let i = 0; i <= 9; i++) {
    clusters.push(tintColor(theme, Number((i / 10).toFixed(2))))
  }
  clusters.push(shadeColor(theme, 0.1))
  return clusters
}

function getCSSString(variable) {
  Vue.prototype.$theme[variable] = css
}

function updateStyle(style, oldCluster, newCluster) {
  let newStyle = style
  oldCluster.forEach((color, index) => {
    newStyle = newStyle.replace(new RegExp(color, 'ig'), newCluster[index])
  })
  return newStyle
}

function getThemeHandler(variable, id, themeCluster) {
  return () => {
    const originalCluster = getThemeCluster(ORIGINAL_THEME.replace('#', ''))
    const newStyle = updateStyle(
      Vue.prototype.$theme[variable],
      originalCluster,
      themeCluster
    )

    let styleTag = document.getElementById(id)
    if (!styleTag) {
      styleTag = document.createElement('style')
      styleTag.setAttribute('id', id)
      document.head.appendChild(styleTag)
    }
    styleTag.innerText = newStyle
  }
}

function setTheme(val) {
  const oldVal = Vue.prototype.$theme.chalk
    ? Vue.prototype.$theme.theme
    : ORIGINAL_THEME
  if (typeof val !== 'string') return
  const theme = val.indexOf('#') !== -1 ? val.substr(1).toLowerCase() : val
  window.localStorage.setItem('theme', theme)
  const themeCluster = getThemeCluster(val.replace('#', ''))
  const originalCluster = getThemeCluster(oldVal.replace('#', ''))
  const chalkHandler = getThemeHandler('chalk', 'chalk-style', themeCluster)
  chalkHandler()
  const styles = [].slice
    .call(document.querySelectorAll('style'))
    .filter(style => {
      const text = style.innerText
      return new RegExp(oldVal, 'i').test(text) && !/Chalk Variables/.test(text)
    })
  styles.forEach(style => {
    const { innerText } = style
    if (typeof innerText !== 'string') return
    style.innerText = updateStyle(innerText, originalCluster, themeCluster)
  })
}

export default (Vue, options) => {
  const chalkTheme = {
    chalk: '',
    theme: Vue.prototype.$utils.getLocalStorage('theme')
      ? '#' + Vue.prototype.$utils.getLocalStorage('theme')
      : ORIGINAL_THEME,
    setTheme: val => {
      getCSSString('chalk')
      setTheme(val)
    },
  }
  Vue.prototype.$theme = chalkTheme
}
